package com.vhall.component.framework.oss.client.impl.sandstone;

import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.amazonaws.ClientConfiguration;
import com.amazonaws.Protocol;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.S3ClientOptions;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.PutObjectRequest;
import com.amazonaws.services.s3.model.PutObjectResult;
import com.vhall.component.framework.common.support.RequestUrlThreadLocal;
import com.vhall.component.framework.oss.client.OssResult;
import com.vhall.component.framework.oss.client.impl.AbstractOssClient;
import com.vhall.component.framework.oss.enums.GuoXinOssUrlEnum;
import com.vhall.component.framework.oss.properties.OssProperties;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
import java.text.MessageFormat;
import java.time.LocalDateTime;

/**
 * @author shimingming
 * @since 2023/9/18 15:15
 */
@Slf4j
public class SandStoneClient extends AbstractOssClient {

    private volatile AmazonS3 amazonS3Client;

    public SandStoneClient(OssProperties properties) {
        super(properties, new SandStoneClientMapping());
    }

    @Override
    protected void doInit() {
        //创建AWS凭证
        AWSCredentials credentials = new BasicAWSCredentials(properties.getAppId(), properties.getSecretKey());
        //初始化客户端config
        ClientConfiguration connconfig = new ClientConfiguration();
        //设置mos 请求协议为http
        connconfig.setProtocol(Protocol.HTTP);

        //使用AWS凭证和clientConfiguration初始化AmazonS3Client客户端
        amazonS3Client = new AmazonS3Client(credentials, connconfig);
        //设置mos对象服务接口地址
        amazonS3Client.setEndpoint(properties.getEndpoint());
        amazonS3Client.setS3ClientOptions(S3ClientOptions.builder().setPathStyleAccess(true).disableChunkedEncoding().build());
        log.info("初始化 initS3Client 完毕");
    }

    @Override
    protected OssResult<String> doUpload(String name, String contentType, InputStream stream) throws IOException {
        String requestId = LocalDateTimeUtil.format(LocalDateTime.now(), "yyyyMMddHHmmssSSSSSS");
        try {
            log.info(MessageFormat.format("开始上传：【{0}】 【{1}】", requestId, name));
            //初始化对象元数据
            ObjectMetadata metadata = new ObjectMetadata();
            metadata.setContentType(contentType);
            metadata.addUserMetadata("x-amz-meta-title", "someTitle");
            /*
             json文件上传要配置Content-Disposition：inline，意在通知客户端可以直接打开读取文件内容，否则会影响到APP对json内容的读取

             而另外一个 Content-Disposition：attachment 是通知客户端该链接是个附件，需下载下来
             */

            if (name.endsWith(".json")) {
                metadata.setContentDisposition("inline");
            }

//        FileInputStream fileInputStream = new FileInputStream(file_name);
            //设置对象元数据
            PutObjectRequest putObjectRequest = new PutObjectRequest(properties.getBucket(), name, stream, metadata);

            PutObjectResult putObjectResult = amazonS3Client.putObject(putObjectRequest);
            log.info(MessageFormat.format("上传返回对象：【{0}】", JSON.toJSONString(putObjectResult)));


            ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            String requestUrl = "";
            if (servletRequestAttributes != null) {
                HttpServletRequest request = servletRequestAttributes.getRequest();
                requestUrl = request.getRequestURL().toString();
            } else {
                // 单独处理一下抽奖的文件上传
                if (name.contains("lottery")) {
                    requestUrl = RequestUrlThreadLocal.getRequestUrl();
                    if (StrUtil.isEmpty(requestUrl)) {
                        requestUrl = "";
                    }
                }
            }

            String url = MessageFormat.format("{0}/{1}", StringUtils.isNotBlank(GuoXinOssUrlEnum.prodJudgeAndReturnClientDomain(requestUrl))
                            ? GuoXinOssUrlEnum.prodJudgeAndReturnClientDomain(requestUrl) : properties.getForwardDomainName()
                    , name);

            log.info(MessageFormat.format("上传返回url：【{0}】", url));
            return OssResult.build("200", "success", requestId, url, codeMapping);
        } catch (Exception ex) {
            ex.printStackTrace();
            log.error("上传 SandStone失败:", ex);
            return OssResult.build("500",
                    ex.getMessage(),
                    requestId,
                    "",
                    codeMapping);
        }

    }
}
